package org.bdware.irs.server.http;

import org.bdware.irs.backend.servicesImpl.BDIrsStorageImpl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import org.apache.log4j.Logger;
import org.bdware.irp.stateinfo.StateInfoBase;
import org.rocksdb.RocksDBException;

import java.util.HashMap;
import java.util.Map;

public class IrsHandler extends RegisterHandler {

    BDIrsStorageImpl store;


    static Logger logger = Logger.getLogger(IrsHandler.class);

    public IrsHandler(BDIrsStorageImpl store) {
        this.store = store;
    }

    @Override
    public Map<String, String> HandleRequest(Map<String, String> postInfo) {

        logger.info("=====receive info=====");
        logger.info(new Gson().toJson(postInfo));

        Map<String, String> respMap = new HashMap<>();
        String action = postInfo.get("action");
        switch (action) {
            case "resolve":
                respMap = handleResolve(postInfo);
                break;
            case "register":
            case "forceRegister":
                try {
                    respMap = handleRegister(postInfo);
                } catch (RocksDBException e) {
                    e.printStackTrace();
                    respMap.put("status", "0");
                    respMap.put("response", "respond failed from LHS");
                }
                break;
            case "unregister":
            case "forceDelete":
                respMap = handleUnRegister(postInfo);
                break;
            case "reregister":
                respMap = handleReRegister(postInfo);
                break;
            case "getRepAnRegs":
                break;
            case "getUsers":
                break;
            default:
                logger.info("error response");
        }
        return respMap;
    }

    public Map<String, String> handleRegister(Map<String, String> reqMap) throws RocksDBException {

        Map<String, String> respMap = new HashMap<>();
        String doType;
        switch (reqMap.get("hrType")) {
            case "do":
                doType = "do";
                break;
            case "dou":
                doType = "dou";
                break;
            case "org/bdware/doip":
                doType = "doip";
                break;
            default:
                doType = "ukw";
                break;
        }
        reqMap.remove("action");
        reqMap.remove("hrType");

        //批量创建的接口,这里我们没有做判断标识是否会生成重复，后期需要考虑一下
        if (reqMap.get("count") != null) {
            int count = Integer.parseInt(reqMap.get("count"));
            reqMap.remove("count");
            String handleRecord = new Gson().toJson(reqMap);
            store.createStateInfo(new StateInfoBase(mapToJsonObject(reqMap)), doType);
            JsonArray ids = new JsonArray();
            for (int i = 1; i < count; i++) {
                handleRecord = new Gson().toJson(reqMap);
                String id = store.createStateInfo(new StateInfoBase(mapToJsonObject(reqMap)), doType);
                ids.add(id);
            }
            respMap.put("identifier", new Gson().toJson(ids));
            respMap.put("status", "1");
            respMap.put("response", "register DO success, count: " + count);
        } else {
            String handleRecord = new Gson().toJson(reqMap);
            String id = store.createStateInfo(new StateInfoBase(mapToJsonObject(reqMap)), doType);
            logger.info("successful update do, identifier: " + id);
            respMap.put("identifier", id);
            respMap.put("status", "1");
            respMap.put("response", "register DO success, identifier: " + id);
        }
        return respMap;
    }

    public Map<String, String> handleReRegister(Map<String, String> reqMap) {
        Map<String, String> respMap = new HashMap<>();
        String identifier;
        if (reqMap.get("identifier") != null) {
            identifier = reqMap.get("identifier");
        } else {
            respMap.put("status", "0");
            respMap.put("response", "identifier not found");
            return respMap;
        }
        try {
            reqMap.remove("action");
            reqMap.remove("hrType");
            String handleRecord = new Gson().toJson(reqMap);

            logger.info("reregister : " + handleRecord);

            //TODO @liuyi 这里需要测试一下，type和hrType要对应一下
            store.deleteStateInfoByID(identifier);
            store.saveStateInfo(new StateInfoBase(identifier, mapToJsonObject(reqMap)));

            logger.info("successful update do, identifier: " + identifier);
            respMap.put("identifier", identifier);
            respMap.put("status", "1");
            respMap.put("response", "reRegister DO success, identifier: " + identifier);
        } catch (Exception e) {
            e.printStackTrace();
            respMap.put("status", "0");
            respMap.put("response", "unregister failed: " + e.getMessage());
        }
        return respMap;
    }

    JsonObject mapToJsonObject(Map<String, String> map) {
        JsonObject jsonObject = new JsonObject();
        for (String key : map.keySet()) {
            jsonObject.addProperty(key, map.get(key));
        }
        return jsonObject;
    }

    public Map<String, String> handleUnRegister(Map<String, String> reqMap) {
        Map<String, String> respMap = new HashMap<>();
        String identifier;
        if (reqMap.get("identifier") != null) identifier = reqMap.get("identifier");
        else {
            respMap.put("status", "0");
            respMap.put("response", "identifier not found");
            return respMap;
        }
        try {
            store.deleteStateInfoByID(identifier);
            respMap.put("status", "1");
            respMap.put("response", "success delete: " + identifier);
        } catch (Exception e) {
            e.printStackTrace();
            respMap.put("status", "0");
            respMap.put("response", "unregister failed: " + e.getMessage());
        }
        return respMap;
    }

    public Map<String, String> handleResolve(Map<String, String> reqMap) {
        Map<String, String> respMap = new HashMap<>();
        String identifier;
        if (reqMap.get("identifier") != null) identifier = reqMap.get("identifier");
        else {
            respMap.put("status", "0");
            respMap.put("response", "identifier not found");
            return respMap;
        }
        try {
            if (store.getStateInfoByID(identifier) == null) {
                respMap.put("status", "0");
                respMap.put("response", "not exist");
                return respMap;
            }
            String result = new Gson().toJson(store.getStateInfoByID(identifier));
            respMap = new Gson().fromJson(result, HashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
            respMap.put("status", "0");
            respMap.put("response", "resolve failed: " + e.getMessage());
        }
        return respMap;
    }
}

